'use strict';

const Service = require('egg').Service;

class CommentService extends Service {
  constructor(ctx) {
    super(ctx);
    this.user = {};
  }

  async create(params) {
    const { mysql } = this.app;
    try {
      const {
        topicId,
        topicType,
        content,
      } = params;
      const from_userid = this.ctx.user.id;
      const created_at = new Date();
      const updated_at = new Date();
      const result = await mysql.query(`INSERT INTO cms_comment(topic_id, topic_type, content, from_userid, created_at, updated_at)
        VALUES (?, ?, ?, ?, ?, ?)`,
      [ topicId, topicType, content, from_userid, created_at, updated_at ]);

      if (result.affectedRows === 1) {
        return result.insertId;
      }
    } catch (error) {
      this.ctx.throw(500, error.message);
    }
  }

  async find(params) {
    const { mysql } = this.app;
    const { helper: { pagination } } = this.ctx;

    try {
      const { topicId, topicType, content, page, size } = params;
      const pagger = pagination(page, size);
      const filters = {
        topic_id: { '=': topicId },
        topic_type: { '=': topicType },
        content: { REGEXP: content },
      };
      const segments = [];
      const values = [];
      Object.keys(filters).forEach(key => {
        const item = filters[key];
        const k = Object.keys(item)[0];
        if (item[k]) {
          segments.push(`(${key} ${k} ? )`);
          values.push(item[k]);
        }
      });

      const select = 'SELECT A.`id`, A.`topic_id`, A.`topic_type`, A.`content`, A.`from_userid`, A.`created_at`, A.`updated_at`, B.`id` as user_id, B.`nick_name` FROM `cms_comment` AS A LEFT JOIN (SELECT U.`id`, I.`email`, I.`nick_name`, I.`age` FROM `sys_user` U LEFT JOIN ( SELECT * FROM `sys_user_info` ) I ON ( U.`id` = I.`user_id` )) AS B ON ( A.`from_userid` = B.`id` )';
      const wheres = segments.length ? `WHERE ${segments.join(' OR ')}` : '';
      const order = 'ORDER BY `updated_at` DESC';
      const limit = 'LIMIT ? OFFSET ?';

      const count = await mysql.query('SELECT COUNT(*) as total FROM (' + select + ') C ' + wheres, [ ...values ]);
      const result = await mysql.query([ select, wheres, order, limit ].join(' '), [ ...values, pagger.limit, pagger.offset ]);

      return {
        pagination: {
          total: count[0].total,
          page: pagger.page,
          size: pagger.size,
        },
        list: result,
      };

    } catch (error) {
      this.ctx.throw(500, error.message);
    }
  }

  async findOne(params) {
    const { mysql } = this.app;
    try {
      const { id } = params;
      const select = 'SELECT A.`id`, A.`topic_id`, A.`topic_type`, A.`content`, A.`from_userid`, A.`created_at`, A.`updated_at`, B.`id`, B.`nick_name` FROM `cms_comment` AS A LEFT JOIN (SELECT U.`id`, I.`email`, I.`nick_name`, I.`age` FROM `sys_user` U LEFT JOIN ( SELECT * FROM `sys_user_info` ) I ON ( U.`id` = I.`user_id` )) AS B ON ( A.`from_userid` = B.`id` )';
      const wheres = 'WHERE A.`id` = ?';
      const result = await mysql.query([ select, wheres ].join(' '), [ id ]);
      if (result.length) {
        return result[0];
      }
      this.ctx.throw(404, 'the id was not found');
    } catch (error) {
      this.ctx.throw(error.status || 500, error.message);
    }
  }

  async update(params) {
    const { mysql } = this.app;
    try {
      const {
        id,
        content,
      } = params;
      const from_userid = this.ctx.user.user_id;
      const updated_at = new Date();
      const result = await mysql.query('UPDATE `cms_comment` SET `content`=?, `from_userid`=?, `updated_at`=? where `id`=?',
        [ content, from_userid, updated_at, id ]);

      if (result.affectedRows === 1) {
        return result.insertId;
      }
    } catch (error) {
      this.ctx.throw(500, error.message);
    }
  }

  async destroy(params) {
    const { mysql } = this.app;
    try {
      const { id } = params;
      const result = await mysql.delete('cms_comment', { id });
      if (result.affectedRows === 1) {
        return {};
      }
    } catch (error) {
      this.ctx.throw(500, error.message);
    }
  }
}

module.exports = CommentService;
